using System;
using System.Diagnostics.Contracts;
using Moq;

namespace Beaker.Specs
{
	/// <summary>
	/// A baseclass for a builder specialized in building mocks.
	/// </summary>
	/// <typeparam name="TMocked">The interface to build a mock for.</typeparam>
	public abstract class MockBuilder<TMocked>
		: Builder<TMocked>
		where TMocked : class
	{
		public MockBuilder()
		{
			Contract.Requires<ArgumentException>(typeof(TMocked).IsInterface, "The mocked type should be an interface.");
		}

		public override TMocked Build()
		{
			return BuildMock().Object;
		}

		/// <summary>
		/// Build the mock
		/// </summary>
		/// <returns>The mock that was created</returns>
		public Mock<TMocked> BuildMock()
		{
			var mock = new Mock<TMocked>();
			SetupMock(mock);
			return mock;
		}

		/// <summary>
		/// Override to add extra setups to the mock
		/// </summary>
		/// <param name="mock">The mock to add extra setups to.</param>
		protected virtual void SetupMock(Mock<TMocked> mock)
		{
		}
	}
}